package com.arch.dev.client.controller;

import java.util.Date;
import java.util.List;
import java.util.Set;

import com.arch.dev.client.ExcelService;
import com.arch.dev.client.ExcelServiceAsync;
import com.arch.dev.client.GreetingService;
import com.arch.dev.client.GreetingServiceAsync;
import com.arch.dev.client.PdfService;
import com.arch.dev.client.PdfServiceAsync;
import com.arch.dev.client.Util.BudgetCalcConstants;
import com.arch.dev.client.Util.BudgetCalcUtil;
import com.arch.dev.client.view.AddBudgetView;
import com.arch.dev.client.view.BudgetCalculatorView;
import com.arch.dev.client.view.CatagoryView;
import com.arch.dev.client.view.DateSearchView;
import com.arch.dev.client.view.EditBudgetDialogView;
import com.arch.dev.client.view.EditBudgetView;
import com.arch.dev.client.view.FormView;
import com.arch.dev.client.view.MakeBusy;
import com.arch.dev.client.view.PDFTableView;
import com.arch.dev.client.view.UsersView;
import com.arch.dev.client.view.chart.ExpenditureChart;
import com.arch.dev.client.view.chart.GraphView;
import com.arch.dev.client.vo.BudgetVO;
import com.arch.dev.client.vo.CatagoryVO;
import com.arch.dev.client.vo.ExcelVO;
import com.arch.dev.client.vo.PdfVO;
import com.arch.dev.client.vo.UserVO;
import com.arch.dev.client.vo.YearVO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.gchart.client.GChart;

public class BudgetController {

	public static String DELETE_MESSAGE = "Deleting";
	
	public static String LOADING_MESSAGE = "Loading";
	
	public static String ADDING_MESSAGE = "Adding";
	
	public static String GENERATE_MESSAGE = "Generating";
	
	GreetingServiceAsync service = GWT.create(GreetingService.class);
	
	PdfServiceAsync pdfService = GWT.create(PdfService.class);
	
	ExcelServiceAsync excelService = GWT.create(ExcelService.class);

	private static BudgetController budgetController = new BudgetController();

	public static BudgetController getInstance() {
		return budgetController;
	}

	public void getAllValues(final Widget view) {
		
		MakeBusy.getInstance().makeBusy(true,LOADING_MESSAGE);

		service.getAllValues(new AsyncCallback<List<BudgetVO>>() {

			public void onSuccess(List<BudgetVO> budgetVOs) {

				// view.populateflexTable(result);

				/*
				 * view.addPanelToRightHorizontalPanel(view
				 * .getBudgetVerticalPanel());
				 */
				if(view instanceof AddBudgetView){
					((AddBudgetView) view).budgetTable.populateflexTable(budgetVOs);

				}else if(view instanceof EditBudgetView){
					((EditBudgetView) view).budgetTable.populateflexTable(budgetVOs);
				}
				MakeBusy.getInstance().makeBusy(false);
			}

			public void onFailure(Throwable caught) {
				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub

			}

		});

	}

	public void persistValues(final Widget view, BudgetVO budgetVO) {

		service.persistValues(budgetVO, new AsyncCallback() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				if (view instanceof AddBudgetView) {
					BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.RECORD_SAVED);
					//((AddBudgetView) view).setSavedMessage("Record Saved ...");
					getAllValues(view);

				} else if (view instanceof EditBudgetView) {
					EditBudgetView editBudgetView = (EditBudgetView) view;					
					if(editBudgetView.dateSearchView.filterType == DateSearchView.Types.DATE){
						getDataForDate(new Date(editBudgetView.getDateSearchView().getDateBox()
								.getValue()), editBudgetView);
					}else if(editBudgetView.dateSearchView.filterType == DateSearchView.Types.ALL){
						getAllValues(editBudgetView);
					}else if(editBudgetView.dateSearchView.filterType == DateSearchView.Types.MONTH){
						getMonthlyDataForYear(Integer.parseInt(editBudgetView.dateSearchView.getSelectedYear()), Integer.parseInt(editBudgetView.dateSearchView.getSelectedMonth()), false, editBudgetView);
					
					}else if(editBudgetView.dateSearchView.filterType == DateSearchView.Types.YEAR){
						getYearlyData(Integer.parseInt(editBudgetView.dateSearchView.getSelectedYear()), false, editBudgetView);
						
					}
					

				}

			}

		});

	}

	
	public void persistCatagoryValues(final Widget view, CatagoryVO catagoryVO) {

		service.persistCatagoryValues(catagoryVO, new AsyncCallback() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				if (view instanceof CatagoryView) {
					BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.RECORD_SAVED);
				//	((AddBudgetView) view).setSavedMessage("Record Saved ...");
					getAllCatagories(view);

				} 
			}

		});

	}
	
	public void getAllCatagories(final Widget view) {
		
		MakeBusy.getInstance().makeBusy(true, LOADING_MESSAGE);

		service.getAllCatagories(new AsyncCallback<List<CatagoryVO>>() {

			public void onFailure(Throwable caught) {

				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub

			}

			public void onSuccess(List<CatagoryVO> catagoryVOs) {
				if(view instanceof FormView){
					((FormView) view).populateCatagoryListBox(catagoryVOs);
				}else if(view instanceof CatagoryView){
					((CatagoryView) view).catagoryTable.populateflexTable(catagoryVOs);
					
				}else if(view instanceof EditBudgetDialogView){
					EditBudgetDialogView editBudgetDialogView = ((EditBudgetDialogView) view);
					editBudgetDialogView.formView.populateCatagoryListBox(catagoryVOs);
					editBudgetDialogView.populateFields(editBudgetDialogView.getBudgetVO());
				}
				
				MakeBusy.getInstance().makeBusy(false);
			}

		});

	}

	public void deleteValues(final Widget view, Set<BudgetVO> budgetVOs) {

		service.deleteValues(budgetVOs, new AsyncCallback() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.RECORD_DELETED);
				
				getAllValues(view);

			}

		});

	}
	

	public void deleteCatagoryValues(final Widget view, Set<CatagoryVO> catagoryVOs) {

		service.deleteCatagoryValues(catagoryVOs, new AsyncCallback() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				/*if(view instanceof CatagoryView){
					((AddBudgetView) view).setDeleteMessage("Record Deleted ...");
				}*/
				BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.RECORD_DELETED);
				getAllCatagories(view);

			}

		});

	}

	/*
	 * public void getMonthlyData(final GChart view) {
	 * 
	 * service.getMonthlyConsolidatedData(new AsyncCallback<List<BudgetVO>>() {
	 * 
	 * public void onFailure(Throwable caught) {
	 * 
	 * // TODO Auto-generated method stub
	 * 
	 * }
	 * 
	 * public void onSuccess(List<BudgetVO> budgetVOs) {
	 * 
	 * ((GChartExample01) view).processData(budgetVOs);
	 * 
	 * // chart.update();
	 * 
	 * }
	 * 
	 * });
	 * 
	 * }
	 */

	public void getDateData(final Widget view) {

		service.getDateData(new AsyncCallback<Set<YearVO>>() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Set<YearVO> yearVOs) {
				if(view instanceof GraphView){
					((GraphView) view).populateYearlyListBox(yearVOs);
				}else if(view instanceof DateSearchView){
					((DateSearchView) view).populateYearlyListBox(yearVOs);
				}
				

			}

		});

	}

	public void getMonthlyDataForYear(int year, int month, boolean isConsolidated, final Widget view) {

		service.getMonthlyDataForYear(year, month, isConsolidated,
				new AsyncCallback<List<BudgetVO>>() {

					public void onFailure(Throwable caught) {

						// TODO Auto-generated method stub

					}

					public void onSuccess(List<BudgetVO> budgetVOs) {						
						if(view instanceof GraphView){
							GChart chart = ((GraphView) view).getGraphWidget();

							((ExpenditureChart) chart).processData(budgetVOs);

							chart.update();	
							
						}else if(view instanceof EditBudgetView){
							((EditBudgetView) view).budgetTable.populateflexTable(budgetVOs);
						}						

					}

				});

	}

	/*public void generatePDF(final Widget view) {

		service.generatePDF(new AsyncCallback<PdfVO>() {

			public void onFailure(Throwable caught) {

			}

			public void onSuccess(PdfVO pdfVO) {

				getAllPDFValues(view);

			}

		});

	}*/

	public void getAllPDFValues(final Widget view) {

		MakeBusy.getInstance().makeBusy(true, LOADING_MESSAGE);
		
		service.getAllPDFValues(new AsyncCallback<List<PdfVO>>() {

			public void onFailure(Throwable caught) {
				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub

			}

			public void onSuccess(List<PdfVO> pdfVOs) {

				if (view instanceof PDFTableView){
					((PDFTableView) view).getPdfTable().populateTable(pdfVOs);
				}else {

					((BudgetCalculatorView) view).populatePdfflexTable(pdfVOs);

				}
				
				MakeBusy.getInstance().makeBusy(false);
			}

		});

	}
	
	
	public void generatePDF(final Widget view) {
		MakeBusy.getInstance().makeBusy(true, GENERATE_MESSAGE);

		service.getAllValues(new AsyncCallback<List<BudgetVO>>() {

			
			public void onSuccess(List<BudgetVO> budgetVOs) {

				pdfService.generatePDF(budgetVOs, new AsyncCallback<PdfVO>() {

					public void onFailure(Throwable caught) {
						MakeBusy.getInstance().makeBusy(false);
					}

					public void onSuccess(PdfVO pdfVO) {

						service.savePDF(pdfVO, new AsyncCallback<PdfVO>() {

							public void onFailure(Throwable caught) {

								// TODO Auto-generated method stub

							}

							public void onSuccess(PdfVO result) {
								BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.PDF_GENERATED);
								getAllPDFValues(view);

							}

						});
						
						
					}

				});
				MakeBusy.getInstance().makeBusy(false);
			}

			
			public void onFailure(Throwable caught) {
				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub

			}

		});

	}

  
	
	
	

	public void getDataForDate(Date selectedDate, final Widget view) {
		
		MakeBusy.getInstance().makeBusy(true, LOADING_MESSAGE);

		service.getDataForDate(selectedDate,
				new AsyncCallback<List<BudgetVO>>() {

					public void onFailure(Throwable caught) {
						MakeBusy.getInstance().makeBusy(false);
					}

					public void onSuccess(List<BudgetVO> budgetVOs) {
						MakeBusy.getInstance().makeBusy(false);
						if (view instanceof EditBudgetView) {
							((EditBudgetView) view).budgetTable
									.populateflexTable(budgetVOs);
						} else if (view instanceof AddBudgetView) {
							((AddBudgetView) view).budgetTable
									.populateflexTable(budgetVOs);
						}

					}

				});

	}

	public void getYearlyData(int year, boolean isConsolidated, final Widget view) {

		service.getYearlyData(year, isConsolidated, new AsyncCallback<List<BudgetVO>>() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(List<BudgetVO> budgetVOs) {

				if(view instanceof GraphView){
					GChart chart = ((GraphView) view).getGraphWidget();

					((ExpenditureChart) chart).processData(budgetVOs);

					chart.update();			
					
				}else if(view instanceof EditBudgetView){
					((EditBudgetView) view).budgetTable.populateflexTable(budgetVOs);
				}
				
				

			}

		});

	}
	
	public void deletePdfValues(final Widget view, final Set<PdfVO> pdfVOs) {
		MakeBusy.getInstance().makeBusy(true, DELETE_MESSAGE);
		service.deletePDF(pdfVOs, new AsyncCallback() {

			public void onFailure(Throwable caught) {

				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				
				pdfService.deletePDF(pdfVOs, new AsyncCallback() {

					
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}

					
					public void onSuccess(Object result) {
						MakeBusy.getInstance().makeBusy(false);
						BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.PDF_DELETED);
						getAllPDFValues(view);
						
					}
				});
				
			}

		});

	}
	
	
	public void processDataFromExcel(final Widget view, final String excelFileName) {
		MakeBusy.getInstance().makeBusy(true);
		service.processDataFromExcel(excelFileName, new AsyncCallback() {

			public void onFailure(Throwable caught) {
				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub

			}

			public void onSuccess(Object result) {
				MakeBusy.getInstance().makeBusy(false);
				
				getAllValues(view);
			
			}

		});

	}
	
	public void generateFilterPDF(final List<BudgetVO> budgetVOs, final Widget view) {
		MakeBusy.getInstance().makeBusy(true, GENERATE_MESSAGE);

				pdfService.generatePDF(budgetVOs, new AsyncCallback<PdfVO>() {

					public void onFailure(Throwable caught) {

					}

					public void onSuccess(PdfVO pdfVO) {

						service.savePDF(pdfVO, new AsyncCallback<PdfVO>() {

							public void onFailure(Throwable caught) {
								MakeBusy.getInstance().makeBusy(false);

								// TODO Auto-generated method stub

							}

							public void onSuccess(PdfVO result) {
								MakeBusy.getInstance().makeBusy(false);
								BudgetCalcUtil.updateMessagePanelMessage(BudgetCalcConstants.PDF_GENERATED);
								((EditBudgetView)view).getPDFFromServer(result);
								
								

							}

						});

					}

				});


	}
	
	public void getALLUsers(final Widget view){
		
		service.getAllUserValues(new AsyncCallback<List<UserVO>>() {

			@Override
			public void onFailure(Throwable arg0) {				
				
			}

			@Override
			public void onSuccess(List<UserVO> UserVOs) {
				((UsersView)view).populateTable(UserVOs);
			}
		});
		
		
	}

	public void persistUserValues(final Widget view, UserVO userVO) {
		
		service.persistUserValues(userVO, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable arg0) {
				
				
			}

			@Override
			public void onSuccess(Void arg0) {
				
				((UsersView)view).refresh();
				
			}
		});
	}
	
	
	public void generateExcel(final Widget view, List<BudgetVO> budgetVOs){
		
		MakeBusy.getInstance().makeBusy(true, GENERATE_MESSAGE);
		excelService.generateExcel(budgetVOs, new AsyncCallback<ExcelVO>() {

			@Override
			public void onFailure(Throwable arg0) {
				MakeBusy.getInstance().makeBusy(false);
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(ExcelVO excelVO) {
				MakeBusy.getInstance().makeBusy(false);
				((EditBudgetView)view).getExcelFromServer(excelVO);
				
			}
		});
	}
	
	
	public void deleteUserValues(final Widget view, Set<UserVO> userVOs) {
		
		MakeBusy.getInstance().makeBusy(true, GENERATE_MESSAGE);
		
		service.deleteUserValues(userVOs, new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable arg0) {				
			   MakeBusy.getInstance().makeBusy(false);
			}

			@Override
			public void onSuccess(Void arg0) {
				MakeBusy.getInstance().makeBusy(false);
				((UsersView)view).refresh();
				
			}
		});
	}
	
	
}
